<!-- 参数配置的曲线显示 -->
<script setup lang="ts">
import { ref, onMounted, watch } from 'vue';
import { sensorByIdData, sensorByIdDvalue, sensorByIdDiff } from "@T2/service/api.ts";
import { colorToRgba } from '@T2/utils/utils.ts';
import * as echarts from 'echarts';
import type { ECharts, EChartsOption, Color, YAXisComponentOption, XAXisComponentOption, LegendComponentOption, SeriesOption } from 'echarts';
import dayjs, { Dayjs } from 'dayjs';

interface ParamsType {
  t: 'c' | 'cy' | 'cm' | 'cd' | 'ch';
  n: string;
  s: number;
}
const props = withDefaults(defineProps<{
  groups: ParamsType[];
  groupDex: number;
  curDate?: Dayjs;  //不传则显示最近24小时的数据
  colors?: string[];
}>(), {
  groupDex: 0,
  colors: () => ['#0082D9', '#C9FFFF', '#0FF6F0', '#7585A2'],
});

let chartRef = ref<HTMLDivElement | null>(null);
let myChart: ECharts | null = null;
onMounted(() => {
  myChart = echarts.init(chartRef.value);
  beforeGetData();
});
watch(() => props.groupDex, (nv, ov) => {
  beforeGetData();
});
const chartsData: EChartsOption = {
	backgroundColor: 'rgba(0, 18, 24, 0)',    //默认，无背景颜色
  color: props.colors,
	grid: {
	  containLabel: true,                 //默认，为true表示外边 距离 包含刻度标签在内的整个图表
	  top: 32,                            //网格离容器顶部距离
	  bottom: "3%",                       //默认，网格离容器底部距离
	  left: '4%',                         //默认，网格离容器左侧距离
	  right: '4%',                        //默认，网格离容器右侧距离
	},
  legend: {
		data: [],
    right: 12,
    top: 0,
    itemHeight: 7,                       //图例图形高度
		orient: 'horizontal',
    icon: 'rect',                        //默认，图例icon
    textStyle: {
    	color: '#B2B2B2',                  //图例文字颜色
    	fontSize: 11,                      //图例文字大小
    },
  },
  tooltip: {
    trigger: 'axis',                        //默认，axis坐标轴触发，主要在柱状图，折线图等会使用类目轴的图表中使用。
    backgroundColor: 'rgba(0,28,32,0.96)',  //提示框背景颜色
    borderColor: 'rgba(23,178,178,0.6)',    //提示框边框颜色
    textStyle: {
      color: '#D3F2EE',                     //提示框字体颜色
      fontSize: 14,                         //提示框字体大小
      fontFamily: 'PingFangSC, PingFang SC',
      fontWeight: 500,
    },
  },
  xAxis: {
    type: 'time',                         //默认，时间轴
    splitLine: {
      show: true,
      lineStyle: {
        color: 'rgba(92,204,197,0.24)',
        type: [3, 3],
      }
    },
    axisLine: {
      lineStyle: {
        width: 2,
        color: '#0a2a2d',
      }
    },
    axisTick: {
      show: false,
    },
    axisLabel: {
      color: '#5CCCC5',
      fontSize: 12,
      fontFamily: 'PingFangSC, PingFang SC',
      fontWeight: 400,
      width: 48,
      overflow: 'break',
    },
  },
  yAxis: {
    type: 'value',                        //默认，数值轴
    splitLine: {
      lineStyle: {
        color: 'rgba(92,204,197,0.24)',
        type: [3, 3],
      }
    },
    axisLabel: {
      color: '#5CCCC5',
      fontFamily: 'PingFangSC, PingFang SC',
      fontWeight: 400,
      lineHeight: 16,
      fontSize: 12,                       //刻度标签字体大小
      formatter: function (value) {
        if (value >= 10000) {
          return (value / 10000) + '万';
        }
        return value + '';
      }
    },
    nameTextStyle: {
      color: "#5CCCC5",                   //坐标轴名称字体颜色
      fontSize: 10,                       //坐标轴名称字体大小
    },
  },
};

function beforeGetData() {
  if (!myChart) {
    return;
  }
  myChart.clear();
  chartsData.series = [];
  const type = props.groups[0].t;
  if (type === "c") {
    getCurLine(props.groups);
  } else if (type === "ch") {
    getHourLine(props.groups);
  } else if (type === "cd") {
    getDayLine(props.groups);
  } else if (type === "cm") {
    getMonthBar(props.groups);
  }
}

/* 实时曲线 */
function getCurLine(params: ParamsType[]) {
  let start = '', end = '';
  if (props.curDate) {
    start = dayjs(props.curDate).format("YYYY-MM-DD") + ' 00:00:00';
    end = dayjs(props.curDate).format("YYYY-MM-DD") + ' 23:59:59';
  } else {
    start = dayjs().subtract(1, 'day').format("YYYY-MM-DD HH:mm:ss");
    end = dayjs().format("YYYY-MM-DD HH:mm:ss");
  }
  
  function getData(params: ParamsType) {
  	return new Promise((resolve, reject) => {
  		sensorByIdData({
  			method: "get",
  			id: params.s,
  			params: {
  				page: 1,
  				pagesize: 1000,
  				ordering: "create_time",
  				start,
  				end,
  			},
  		}).then(res => {
  			resolve(res);
  		}).catch(e => {
  			reject(e);
  		});
  	});
  }
  
  chartsData.dataZoom = {
  	type: "inside",
    preventDefaultMouseMove: false,
  };
  Promise.all(params.map(i => getData(i))).then((res: any) => {
    const yAxis = chartsData.yAxis as YAXisComponentOption;
    yAxis.name = res[0].unit;
    const xAxis = chartsData.xAxis as XAXisComponentOption;
    xAxis.min = start;
    xAxis.max = end;
    /* 没招了，就是没属性splitNumber */
    (xAxis as any).splitNumber = 4;
    const axisLabel = xAxis.axisLabel as XAXisComponentOption['axisLabel'];
    /* 没招了，就是没属性formatter */
    (axisLabel as any).formatter = function (value: Dayjs) {
    	return dayjs(value).format('HH:mm');
    };
    (chartsData.tooltip as any).formatter = function (par: any) {
      let time = par.length && dayjs(par[0].data[0]).format("YYYY-MM-DD HH:mm:ss");
      let res = time + '<br />';
      par.forEach((ser: any) => {
      	res = res
      		+ `<span style="display:inline-block;margin-bottom:1px;margin-right:4px;border-radius:5px;width:5px;height:5px;background-color:${ser.color};"></span>`
      		+ ser.seriesName
      		+ `<span style="float:right;margin-left:10px;font-size:10px">${ser.data[1]}${yAxis.name}</span>`
      		+ '<br />'
      });
      return res;
    }
    params.forEach((item: ParamsType, index: number) => initLineOptions(item, index, res[index]));
  });
}
function initLineOptions(params: ParamsType, index: number, res: DvalueType) {
  const series = chartsData.series as SeriesOption[];
  const color = chartsData.color as Color[];
  series.push({
    name: params.n || `-${ index }`,
    type: "line",
    showSymbol: false,
    smooth: true,
    lineStyle: {
    	width: 1,
      shadowColor: colorToRgba(color[index] as string, 0.8),
      shadowBlur: 3,
      shadowOffsetY: 3,
    },
  })
	const { results } = res;
  results.forEach(item => item._data = +item.data);
  series[index].data = results.map((item) => [
  	item.create_time,
  	(item._data)!.toFixed(2),
  ]);
  
  const legend = chartsData.legend as LegendComponentOption;
  legend.data = [];
  legend.data?.push(params.n || `-${ index }`);
  myChart!.setOption(chartsData, true);
}

/* 每小时 */
function getHourLine(params: ParamsType[]) {
  function getHourDvalue(params: ParamsType) {
  	return new Promise((resolve, reject) => {
  		sensorByIdDvalue({
  			method: "get",
  			id: params.s,
  			params: {
  				status: "每小时",
          ordering: "create_time",
  				start: dayjs().format("YYYY-MM-DD") + " 00:00:00",
  			},
  		}).then(res => {
  			resolve(res);
  		}).catch(e => {
  			reject(e);
  		});
  	});
  }
  delete chartsData.dataZoom;
  Promise.all(params.map(i => getHourDvalue(i))).then((res: any) => {
    const yAxis = chartsData.yAxis as YAXisComponentOption;
    yAxis.name = res[0].unit;
    const xAxis = chartsData.xAxis as XAXisComponentOption;
    xAxis.min = dayjs().format("YYYY-MM-DD") + " 00:00:00";
    xAxis.max = dayjs().format("YYYY-MM-DD HH:mm:ss");
    /* 没招了，就是没属性splitNumber */
    (xAxis as any).splitNumber = 4;
    const axisLabel = xAxis.axisLabel as XAXisComponentOption['axisLabel'];
    /* 没招了，就是没属性formatter */
    (axisLabel as any).formatter = function (value: Dayjs) {
    	return dayjs(value).format('HH:mm');
    };
    (chartsData.tooltip as any).formatter = function (par: any) {
      let time = par.length && dayjs(par[0].data[0]).format("YYYY-MM-DD HH时");
      let res = time + '<br />';
      par.forEach((ser: any) => {
      	res = res
      		+ `<span style="display:inline-block;margin-bottom:1px;margin-right:4px;border-radius:5px;width:5px;height:5px;background-color:${ser.color};"></span>`
      		+ ser.seriesName
      		+ `<span style="float:right;margin-left:10px;font-size:10px">${ser.data[1]}${yAxis.name}</span>`
      		+ '<br />'
      });
      return res;
    }
    params.forEach((item: ParamsType, index: number) => initHourLineOptions(item, index, res[index]));
  });
}
interface DvalueType {
  count: number;
  results: { create_time: string; data: string; _data?: number; id: number; }[];
  unit: string;
}
function initHourLineOptions(params: ParamsType, index: number, res: DvalueType) {
  const series = chartsData.series as SeriesOption[];
  const color = chartsData.color as Color[];
  series.push({
    name: params.n || `-${ index }`,
    type: "line",
    showSymbol: true,
    symbol: 'circle',
    smooth: true,
    lineStyle: {
    	width: 1,
      shadowColor: colorToRgba(color[index] as string, 0.8),
      shadowBlur: 3,
      shadowOffsetY: 3,
    },
  })
	const { results } = res;
  results.forEach(item => item._data = +item.data);
  series[index].data = results.map((item) => [
  	dayjs(item.create_time).subtract(1, 'hour').format("YYYY-MM-DD HH") + ":00:00",
  	(item._data)!.toFixed(2),
  ]);
  
  const legend = chartsData.legend as LegendComponentOption;
  legend.data = [];
  legend.data?.push(params.n || `-${ index }`);
  myChart!.setOption(chartsData, true);
}

/* 每日 */
function getDayLine(params: ParamsType[]) {
  function getDayDvalue(params: ParamsType) {
    function getDayDvalueBefore(params: ParamsType) {
      return new Promise((resolve, reject) => {
      	sensorByIdDvalue({
      		method: "get",
      		id: params.s,
      		params: {
      			status: "每日",
      	    ordering: "create_time",
      			start: dayjs().format("YYYY-MM") + "-02 00:00:00",  //每月2日的是1号的水量
      		},
      	}).then(res => {
      		resolve(res);
      	}).catch(e => {
      		reject(e);
      	});
      });
    }
    return new Promise((resolve, reject) => {
      Promise.all([getDayDvalueBefore(params), getIdDiff(params)])
        .then((res: any) => {
          resolve(res);
        })
        .catch((error: any) => {
          reject(error);
        });
    });
  }
  
  delete chartsData.dataZoom;
  Promise.all(params.map(i => getDayDvalue(i))).then((res: any) => {
    const yAxis = chartsData.yAxis as YAXisComponentOption;
    yAxis.name = res[0][0].unit;
    const xAxis = chartsData.xAxis as XAXisComponentOption;
    xAxis.min = dayjs().format("YYYY-MM") + "-01 00:00:00";
    xAxis.max = dayjs().format("YYYY-MM-DD HH:mm:ss");
    /* 没招了，就是没属性splitNumber */
    (xAxis as any).splitNumber = 4;
    const axisLabel = xAxis.axisLabel as XAXisComponentOption['axisLabel'];
    /* 没招了，就是没属性formatter */
    (axisLabel as any).formatter = function (value: Dayjs) {
    	return dayjs(value).format('MM-DD');
    };
    (chartsData.tooltip as any).formatter = function (par: any) {
      let time = par.length && dayjs(par[0].data[0]).format("YYYY-MM-DD");
      let res = time + '<br />';
      par.forEach((ser: any) => {
      	res = res
      		+ `<span style="display:inline-block;margin-bottom:1px;margin-right:4px;border-radius:5px;width:5px;height:5px;background-color:${ser.color};"></span>`
      		+ ser.seriesName
      		+ `<span style="float:right;margin-left:10px;font-size:10px">${ser.data[1]}${yAxis.name}</span>`
      		+ '<br />'
      });
      return res;
    }
    params.forEach((item: ParamsType, index: number) => initDayLineOptions(item, index, res[index]));
  });
}
function initDayLineOptions(params: ParamsType, index: number, res: [DvalueType, DiffType]) {
  const series = chartsData.series as SeriesOption[];
  const color = chartsData.color as Color[];
  series.push({
    name: params.n || `-${ index }`,
    type: "line",
    showSymbol: true,
    symbol: 'circle',
    smooth: true,
    lineStyle: {
    	width: 1,
      shadowColor: colorToRgba(color[index] as string, 0.8),
      shadowBlur: 3,
      shadowOffsetY: 3,
    },
  })
	const { results } = res[0];
	const { today } = res[1];
  results.push({
  	create_time: dayjs().add(1, 'day').format("YYYY-MM-DD") + " 00:00:00",
  	id: -1,
  	data: today.toString(),
  });
  results.forEach(item => item._data = +item.data);
  series[index].data = results.map((item) => [
  	dayjs(item.create_time).subtract(1, 'day').format("YYYY-MM-DD") + " 00:00:00",
  	(item._data)!.toFixed(2),
  ]);
  
  const legend = chartsData.legend as LegendComponentOption;
  legend.data = [];
  legend.data?.push(params.n || `-${ index }`);
  myChart!.setOption(chartsData, true);
}

/* 每月 */
function getMonthBar(params: ParamsType[]) {
  function getMonthDvalue(params: ParamsType) {
    function getMonthDvalueBefore(params: ParamsType) {
      return new Promise((resolve, reject) => {
      	sensorByIdDvalue({
      		method: "get",
      		id: params.s,
      		params: {
      			status: "每月",
      		  ordering: "create_time",
      			start: dayjs().format("YYYY") + "-02-01 00:00:00",	//2月1日的是一月的水量
      		},
      	}).then(res => {
      		resolve(res);
      	}).catch(e => {
      		reject(e);
      	});
      });
    }
    return new Promise((resolve, reject) => {
      Promise.all([getMonthDvalueBefore(params), getIdDiff(params)])
        .then((res: any) => {
          resolve(res);
        })
        .catch((error: any) => {
          reject(error);
        });
    });
  }
  
  delete chartsData.dataZoom;
  Promise.all(params.map(i => getMonthDvalue(i))).then((res: any) => {
    const yAxis = chartsData.yAxis as YAXisComponentOption;
    yAxis.name = res[0][0].unit;
    const xAxis = chartsData.xAxis as XAXisComponentOption;
		xAxis.min = dayjs().format("YYYY") + "-01-01 00:00:00";
		xAxis.max = dayjs().format("YYYY-MM-DD") + " 00:00:00";
    /* 没招了，就是没属性splitNumber */
    (xAxis as any).splitNumber = 4;
    const axisLabel = xAxis.axisLabel as XAXisComponentOption['axisLabel'];
    /* 没招了，就是没属性formatter */
    (axisLabel as any).formatter = function (value: Dayjs) {
    	return dayjs(value).format('MM月');
    };
    (chartsData.tooltip as any).formatter = function (par: any) {
      let time = par.length && dayjs(par[0].data[0]).format("YYYY年MM月");
      let res = time + '<br />';
      par.forEach((ser: any) => {
      	res = res
      		+ `<span style="display:inline-block;margin-bottom:1px;margin-right:4px;border-radius:5px;width:5px;height:5px;background-color:${ser.color};"></span>`
      		+ ser.seriesName
      		+ `<span style="float:right;margin-left:10px;font-size:10px">${ser.data[1]}${yAxis.name}</span>`
      		+ '<br />'
      });
      return res;
    }
    params.forEach((item: ParamsType, index: number) => initMonthBarOptions(item, index, res[index]));
  });
}
function initMonthBarOptions(params: ParamsType, index: number, res: [DvalueType, DiffType]) {
  const series = chartsData.series as SeriesOption[];
  series.push({
    name: params.n || `-${ index }`,
    type: "bar",
    barWidth: '10px',
    itemStyle: {
    	borderRadius: [4, 4, 0, 0],
    },
  })
	const { results } = res[0];
	const { month } = res[1];
  results.push({
  	create_time: dayjs().add(1, 'month').format("YYYY-MM") + "-01 00:00:00",
  	id: -1,
  	data: month.toString(),
  });
  results.forEach(item => item._data = +item.data);
  series[index].data = results.map((item) => [
  	dayjs(item.create_time).subtract(1, 'month').format("YYYY-MM") + "-01 00:00:00",
  	(item._data)!.toFixed(2),
  ]);
  
  const legend = chartsData.legend as LegendComponentOption;
  legend.data = [];
  legend.data?.push(params.n || `-${ index }`);
  myChart!.setOption(chartsData, true);
}


interface DiffType {
  month: number;
  today: number;
  year: number;
  unit: string;
}
function getIdDiff(params: ParamsType) {
	return new Promise((resolve, reject) => {
		sensorByIdDiff({
			method: "get",
			id: params.s,
			params: {},
		}).then(res => {
			resolve(res);
		}).catch(e => {
			reject(e);
		});
	});
}
</script>

<template>
  <div class="echarts-container" ref="chartRef"></div>
</template>

<style lang="scss" scoped>
.echarts-container {
  width: 100%;
  height: 100%;
}
</style>